package middleware

import (
	"context"
	"github.com/golang-jwt/jwt/v5"
	"net/http"
	"private-domain-overseas-service/admin/business/api/internal/config"
	"private-domain-overseas-service/pkg/common"
	"private-domain-overseas-service/pkg/result"
	"private-domain-overseas-service/pkg/xerr"
	"strings"
	"time"
)

type CheckAndFlushTokenMiddleware struct {
	cfg config.Config
	Key string
}

func NewCheckAndFlushTokenMiddleware(cfg config.Config, Key string) *CheckAndFlushTokenMiddleware {
	return &CheckAndFlushTokenMiddleware{
		cfg,
		Key,
	}
}

func (m *CheckAndFlushTokenMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		authHeader := r.Header.Get("Authorization")
		if authHeader == "" {
			result.HttpResult(r, w, nil, xerr.ErrCodeMsg(xerr.ServerAdminPermissionDenied, "Authorization header required"))
			return
		}

		// 获取token
		tokenString := strings.Replace(authHeader, "Bearer ", "", 1)
		token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
				return nil, jwt.ErrSignatureInvalid
			}
			return []byte(m.Key), nil
		})
		if err != nil {
			result.HttpResult(r, w, nil, xerr.ErrCodeMsg(xerr.ServerTokenInvalidError, "无效Token"))
			return
		}

		if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
			// 验证token是否过期
			if expiresAt, ok := claims["exp"].(float64); ok {
				if int64(expiresAt) < time.Now().Unix() {
					result.HttpResult(r, w, nil, xerr.ErrCodeMsg(xerr.ServerTokenExpireError, "Token过期"))
					return
				}
			}

			// 验证token并提取用户信息
			userId, roleIds, buttonIds, err := common.JwtAdminValidate(m.Key, tokenString)
			if err != nil {
				result.HttpResult(r, w, nil, xerr.ErrCodeMsg(xerr.ServerTokenInvalidError, err.Error()))
				return
			}

			// 校验成功把信息添加到上下文
			ctx := r.Context()
			ctx = context.WithValue(ctx, "bsu", userId)
			ctx = context.WithValue(ctx, "rids", roleIds)
			ctx = context.WithValue(ctx, "bids", buttonIds)
			next(w, r.WithContext(ctx))

		} else {
			result.HttpResult(r, w, nil, xerr.ErrCodeMsg(xerr.ServerTokenInvalidError, "无效Token"))
			return
		}
	}
}
